//
// Created by dw on 2021/8/8.
//

#ifndef DATASTRUCTURELEARNING_CHAPTER1_1_5_CURRENCY_H_
#define DATASTRUCTURELEARNING_CHAPTER1_1_5_CURRENCY_H_
#include "../../tools/illegal_parameter_value.h"
#include <iostream>

enum SignType { plus, minus };
class Currency {
 public:
  Currency(SignType sign_type = plus, unsigned long dollars = 0, unsigned int cents = 0) {
    SetValue(sign_type, dollars, cents);
  }

  ~Currency() {}

  void SetValue(SignType sign_type, unsigned long dollars, unsigned int cents) {
    if (cents > 99) {
      throw IllegalParameterValue("Cents should be < 100");
    }
    amount = dollars * 100 + cents;
    if (sign_type == minus) amount = -amount;
  }

  void SetValue(double amount) {
    if (amount < 0) {
      this->amount = (long) ((amount - 0.001) * 100);
    } else {
      this->amount = (long) ((amount + 0.001) * 100);
    }
  }

  SignType GetSign() const {
    if (amount < 0) return minus;
    else return plus;
  }

  unsigned long GetDollars() const {
    if (amount < 0) return (-amount) / 100;
    else return amount / 100;
  }

  unsigned int GetCents() const {
    if (amount < 0) return -amount - GetDollars() * 100;
    else return amount - GetDollars() * 100;
  }

  Currency operator+(const Currency &x) const {
    Currency result;
    result.amount = amount + x.amount;
    return result;
  }

  Currency &operator+=(const Currency &x) {
    amount += x.amount;
    return *this;
  }

  void Output(std::ostream &out) const {
    long theAmount = amount;
    if (theAmount < 0) {
      out << '-';
      theAmount = -theAmount;
    }
    long dollars = theAmount / 100;
    out << '$' << dollars << '.';
    int cents = theAmount - dollars * 100;
    if (cents < 10) {
      out << '0';
    }
    out << cents;
  }

  friend std::ostream &operator<<(std::ostream &out, const Currency &x) {
    long theAmount = x.amount;
    if (theAmount < 0) {
      out << '-';
      theAmount = -theAmount;
    }
    long dollars = theAmount / 100;
    out << '$' << dollars << '.';
    int cents = theAmount - dollars * 100;
    if (cents < 10) {
      out << '0';
    }
    out << cents;
    return out;
  }

 private:
  long amount{};

};

#endif //DATASTRUCTURELEARNING_CHAPTER1_1_5_CURRENCY_H_
